#include "contactuserlist.h"
#include "conuseritem.h"
#include "grouptipitem.h"
#include "tcpmanager.h"
#include "usermanager.h"

#include <QScrollBar>
#include <QRandomGenerator>
#include <QCoreApplication>
#include <QTimer>
#include <QDebug>

ContactUserList::ContactUserList(QWidget *parent) : m_load_pending(false), m_add_friend_item(nullptr)
{
    Q_UNUSED(parent);
    this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    // 安装事件过滤器
    this->viewport()->installEventFilter(this);

    // 从数据库或者后端传输过来的数据,进行列表加载
    addContactUserList();
    //连接点击的信号和槽
    connect(this, &QListWidget::itemClicked, this, &ContactUserList::slot_item_clicked);

    // 连接对端同意认证后通知的信号
    connect(TcpManager::getInstance().get(), &TcpManager::sig_add_auth_friend,this, &ContactUserList::slot_add_auth_firend);

    // 连接自己点击同意认证后界面刷新
    connect(TcpManager::getInstance().get(), &TcpManager::sig_auth_rsp,this, &ContactUserList::slot_auth_rsp);
}

// 有新消息时，显示红点
void ContactUserList::showRedPoint(bool b_show)
{
    m_add_friend_item->showRedPoint(b_show);
}

bool ContactUserList::eventFilter(QObject *watched, QEvent *event)
{
    // 检查事件是否是鼠标悬浮进入或离开
    if (watched == this->viewport()) {
        if (event->type() == QEvent::Enter) {
            // 鼠标悬浮，显示滚动条
            this->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
        } else if (event->type() == QEvent::Leave) {
            // 鼠标离开，隐藏滚动条
            this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        }
    }

    // 检查事件是否是鼠标滚轮事件
    if (watched == this->viewport() && event->type() == QEvent::Wheel) {
        QWheelEvent *wheelEvent = static_cast<QWheelEvent*>(event);
        int numDegrees = wheelEvent->angleDelta().y() / 8;
        int numSteps = numDegrees / 15;         // 计算滚动步数

        // 设置滚动幅度
        this->verticalScrollBar()->setValue(this->verticalScrollBar()->value() - numSteps);

        // 检查是否滚动到底部
        QScrollBar *scrollBar = this->verticalScrollBar();
        int maxScrollValue = scrollBar->maximum();
        int currentValue = scrollBar->value();
        // int pageSize = 10; // 每页加载的联系人数量

        if (maxScrollValue - currentValue <= 0) {
            // 判断联系人是否加载完成
            auto b_loaded = UserManager::getInstance()->isLoadChatFinish();
            if (b_loaded) {
                return true;
            }

            // 判断是否正在加载中
            if (m_load_pending) {
                return true;
            }

            m_load_pending = true;

            QTimer::singleShot(100, [this]() {
                m_load_pending = false;
                // 完成后退出应用程序
                QCoreApplication::quit();
            });

            // 滚动到底部，加载新的联系人
            qDebug() << "load more contact user";
            // 发送信号通知聊天界面加载更多聊天内容
            emit sig_loading_contact_user();
        }

        return true; // 停止事件传递
    }

    return QListWidget::eventFilter(watched, event);
}


void ContactUserList::addContactUserList()
{
    auto* groupTip = new GroupTipItem();
    QListWidgetItem* item = new QListWidgetItem();
    item->setSizeHint(groupTip->sizeHint());
    this->addItem(item);
    this->setItemWidget(item, groupTip);
    item->setFlags(item->flags() & ~Qt::ItemIsSelectable);

    m_add_friend_item = new ConUserItem();
    m_add_friend_item->setObjectName("new_friend_item");
    m_add_friend_item->setInfo(0, tr("新的朋友"),":/res/add_friend.png");
    m_add_friend_item->setItemType(ListItemType::APPLY_FRIEND_ITEM);

    QListWidgetItem* add_item = new QListWidgetItem;
    add_item->setSizeHint(m_add_friend_item->sizeHint());
    this->addItem(add_item);
    this->setItemWidget(add_item, m_add_friend_item);

    // 默认设置新添加的好友申请条目被选中
    this->setCurrentItem(add_item);

    auto* groupCon = new GroupTipItem();
    groupCon->setGroupTip("联系人");
    m_groupitem = new QListWidgetItem;
    m_groupitem->setSizeHint(groupCon->sizeHint());
    this->addItem(m_groupitem);
    this->setItemWidget(m_groupitem, groupCon);
    m_groupitem->setFlags(m_groupitem->flags() & ~Qt::ItemIsSelectable);

    // 加载后端发送过来的好友列表
    auto con_list = UserManager::getInstance()->getConListPerPage();
    for (auto& con_ele : con_list){
        auto *con_user_wid = new ConUserItem();
        con_user_wid->setInfo(con_ele->m_uid, con_ele->m_name, con_ele->m_icon);
        QListWidgetItem *item = new QListWidgetItem;
        //qDebug()<<"chat_user_wid sizeHint is " << chat_user_wid->sizeHint();
        item->setSizeHint(con_user_wid->sizeHint());
        this->addItem(item);
        this->setItemWidget(item, con_user_wid);
    }

    // TODO
    // 创建QListWidgetItem，并设置自定义的widget 测试代码
    /*
    for (int i = 0; i < 13; ++ i) {
        // 生成0到99之间的随机数
        int randomValue = QRandomGenerator::global()->bounded(100);
        int str_i = randomValue%strs.size();
        int head_i = randomValue%heads.size();
        int name_i = randomValue%names.size();

        auto* con_user_wid = new ConUserItem();
        con_user_wid->setInfo(0, names[name_i], heads[head_i]);
        QListWidgetItem* item = new QListWidgetItem;
        item->setSizeHint(con_user_wid->sizeHint());
        this->addItem(item);
        this->setItemWidget(item, con_user_wid);
    }
    */
}

// 处理联系人条目被点击的信号
void ContactUserList::slot_item_clicked(QListWidgetItem *item)
{
    QWidget *widget = this->itemWidget(item); // 获取自定义widget对象
    if (!widget){
        qDebug() << "slot item clicked widget is nullptr";
        return;
    }

    // 对自定义widget进行操作， 将item 转化为基类ListItemBase
    ListItemBase *customItem = qobject_cast<ListItemBase*>(widget);
    if (!customItem) {
        qDebug() << "slot item clicked widget is nullptr";

        return;
    }

    auto itemType = customItem->getListItemType();
    if (itemType == ListItemType::INVALID_ITEM || itemType == ListItemType::GROUP_TIP_ITEM) {
        qDebug() << "slot invalid item clicked ";

        return;
    }

    if (itemType == ListItemType::APPLY_FRIEND_ITEM) {
        // 创建对话框，提示用户
        qDebug() << "apply friend item clicked ";
        // 跳转到好友申请界面
        emit sig_switch_apply_friend_page();

        return;
    }

    if (itemType == ListItemType::CONTACT_USER_ITEM) {
        // 创建对话框，提示用户
        qDebug() << "contact user item clicked ";

        auto con_item = qobject_cast<ConUserItem*>(customItem);
        auto user_info = con_item->getInfo();

        // 跳转到好友申请界面
        emit sig_switch_friend_info_page(user_info);

        return;
    }
}

// 处理对端同意认证后通知的信号
void ContactUserList::slot_add_auth_firend(std::shared_ptr<AuthInfo> auth_info)
{
    qDebug() << "slot add auth friend ";
    bool isFriend = UserManager::getInstance()->checkFriendById(auth_info->m_uid);
    if (isFriend) {
        return;
    }
    // 在 groupitem 之后插入新项
    int randomValue = QRandomGenerator::global()->bounded(100); // 生成0到99之间的随机整数
    int str_i = randomValue % strs.size();
    int head_i = randomValue % heads.size();

    auto *con_user_wid = new ConUserItem();
    con_user_wid->setInfo(auth_info);
    QListWidgetItem *item = new QListWidgetItem;
    //qDebug()<<"chat_user_wid sizeHint is " << chat_user_wid->sizeHint();
    item->setSizeHint(con_user_wid->sizeHint());

    // 获取 groupitem 的索引
    int index = this->row(m_groupitem);
    // 在 groupitem 之后插入新项
    this->insertItem(index + 1, item);

    this->setItemWidget(item, con_user_wid);
}

// 处理己点击同意认证后界面刷新信号（申请列表、好友列表UI的刷新）
void ContactUserList::slot_auth_rsp(std::shared_ptr<AuthRsp> auth_rsp)
{
    qDebug() << "slot auth rsp called";
    bool isFriend = UserManager::getInstance()->checkFriendById(auth_rsp->m_uid);
    if (isFriend) {
        return;
    }
    // 在 groupitem 之后插入新项
    int randomValue = QRandomGenerator::global()->bounded(100); // 生成0到99之间的随机整数
    int str_i = randomValue % strs.size();
    int head_i = randomValue % heads.size();

    auto *con_user_wid = new ConUserItem();
    con_user_wid->setInfo(auth_rsp->m_uid ,auth_rsp->m_name, heads[head_i]);
    QListWidgetItem *item = new QListWidgetItem;
    //qDebug()<<"chat_user_wid sizeHint is " << chat_user_wid->sizeHint();
    item->setSizeHint(con_user_wid->sizeHint());

    // 获取 groupitem 的索引
    int index = this->row(m_groupitem);
    // 在 groupitem 之后插入新项
    this->insertItem(index + 1, item);

    this->setItemWidget(item, con_user_wid);
}
